<template>
  <Spin :spinning="spinning" :delay="20">
    <div :class="['py-4 px-6', prefixCls]">
      <HEditTable
        v-model:data="rawData.schemas[data.client]"
        v-if="columns.length"
        :columns="columns"
        :showAllEdit="true"
        tableClass="dataInfo"
      >
        <template #title>
          <div class="flex pb-3">
            <div class="title flex items-end flex-1">
              <div class="db-name">数据库名：{{ dbRef.dataSource }}</div>
              <div class="table-name ml-13">表名: {{ dbRef.tableCode }}</div>
            </div>
            <div class="actions">
              <a-button @click="getDBFeilds">库表获取</a-button>
              <a-button class="ml-2" @click="getDefineFeilds">定义表获取</a-button>
              <a-button class="ml-2" @click="handleCopyList(data.client == 1 ? 0 : 1)">
                获取{{ data.client == 1 ? 'PC端' : 'APP端' }}配置
              </a-button>
              <a-button class="ml-2" @click="handleAdd">添加隐藏字段</a-button>
              <a-button class="ml-2" @click="handleDelBatch">删除</a-button>
            </div>
          </div>
        </template>
        <template #action="{ record, index }">
          <div class="actions">
            <a-button type="link" class="!mr-1 !px-0" @click.stop="handleCopy(record, index)">
              复制
            </a-button>
            <a-button
              type="link"
              v-if="record[typeField] === ComponentTypeEnum.Hide"
              class="!mr-1 !px-0"
              @click.stop="handleEdit(record, index)"
            >
              编辑
            </a-button>
            <a-button type="link" class="!mx-1 !px-0" @click.stop="handleDel(index)"
              >删除
            </a-button>
          </div>
        </template>
      </HEditTable>
      <FormFieldConfigModal @register="registerFModal" @success="handleSuccess" />
    </div>
  </Spin>
</template>

<script lang="ts" setup name="DataInfoTable">
  import { ref, unref, computed, onMounted, watch } from 'vue';
  import { HEditTable, EditColumn } from '/@/components/HEditTable';
  import FormFieldConfigModal from '/@/views/config-center/model-design/components/FormFieldConfigModal.vue';

  import { dataInfoColumns } from './basic.data';
  import { ModelFormConfig } from './typing';
  import { Spin } from 'ant-design-vue';
  import { isNullOrUnDef } from '/@/utils/is';
  import { ComponentTypeEnum } from '/@/components/ModelTable/index';
  import { sortBy, cloneDeep } from 'lodash-es';

  import { useModal } from '/@/components/Modal';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { DBTableItem } from '/@/api/config-center/model';
  import {
    getFieldsFromDbListApi,
    getFieldsFromTableDefineListApi,
  } from '/@/api/config-center/model-design';

  const { prefixCls } = useDesign('DataInfoTable');
  const props = withDefaults(
    defineProps<{
      data: ModelFormConfig;
    }>(),
    {},
  );
  const { createMessage } = useMessage();

  const rawData = ref<any>({});
  const spinning = ref(true);
  const dbRef = computed(() => props.data.dataInfo || {});
  const typeField = computed(() => 'componentType');

  onMounted(() => {
    init();
  });

  watch(
    () => props.data.client,
    () => {
      init();
    },
  );
  const columns = ref<EditColumn[]>([]);
  async function init() {
    columns.value = await dataInfoColumns();

    const formInfo = props.data.formDesignInfo;
    //  将隐藏字段放到最后
    formInfo.schemas[formInfo.client] = sortBy(
      formInfo.schemas[formInfo.client] || [],
      (a) => a[typeField.value] === ComponentTypeEnum.Hide,
    );

    rawData.value = props.data.formDesignInfo;

    spinning.value = false;
  }

  const handleDelBatch = () => {
    const arr = rawData.value.schemas[props.data.client] || [];
    const data = arr.filter((el) => el.check);
    if (!data.length) {
      createMessage.warn('请先选择要删除的列', 0.8);
      return;
    }

    rawData.value.schemas[props.data.client] = arr.filter((el) => !el.check);
  };
  const handleDel = (index) => {
    rawData.value.schemas[props.data.client].splice(index, 1);
  };
  const [registerFModal, { openModal: schemasModal }] = useModal();

  const handleAdd = () => {
    const index = rawData.value.schemas[props.data.client].length + 1;

    schemasModal(true, {
      record: {
        index,
        componentType: 13,
        component: 'Hide',
        updateType: 0,
        formModelDataType: 2,
        formModelHiddenType: 9,
        componentProps: {},
      },
      isUpdate: true,
      client: props.data.client,
    });
  };

  const handleEdit = (record, index) => {
    record.index = index;

    schemasModal(true, {
      record,
      client: props.data.client,
      isUpdate: true,
    });
  };
  const handleCopy = (record, index) => {
    const item = cloneDeep(record);
    item.field = `copy_${record.field}`;
    item.label = `copy_${record.label}`;
    rawData.value.schemas[props.data.client].splice(index + 1, 0, item);
  };
  const handleCopyList = (client) => {
    const list = rawData.value.schemas[client];
    setTitles(cloneDeep(list), true);
  };

  const handleSuccess = ({ index, record }) => {
    rawData.value.schemas[props.data.client].splice(index, 1, record);
  };
  // ============ 获取字段 start ==========
  const getDBFeilds = async () => {
    const data = await getFieldsFromDbListApi(unref(dbRef));

    setTitles(data);
  };

  const getDefineFeilds = async () => {
    const data = await getFieldsFromTableDefineListApi(unref(dbRef) as DBTableItem);

    setTitles(data);
  };

  async function setTitles(data: any[], flag = false) {
    const titles = unref(rawData).schemas[props.data.client];

    const code = 'field';
    const name = 'label';

    const dataIndexs = titles.map((el) => el[code]);

    const newDataInexs = data
      .filter((el) => !dataIndexs.includes(el[flag ? code : 'name']))
      .map((el) => {
        if (flag) return el;
        return { [name]: el.title || el.name, [code]: el.name };
      });
    const ret = newDataInexs.map((el) => {
      if (flag) return el;
      const defData = getDefValue(columns.value);
      return {
        component: 'Input',
        [typeField.value]: 0,
        componentProps: {},
        ...el,
        ...defData,
      };
    });
    const schemas = titles.concat(ret);

    rawData.value.schemas[props.data.client] = schemas;

    createMessage.success('操作成功', 0.5);
  }

  function getDefValue(columns: any[] = []) {
    const ret = {};

    columns.forEach(({ dataIndex, defaultValue }) => {
      if (!isEmpty(defaultValue)) {
        ret[dataIndex] = defaultValue;
      }
    });

    return ret;
  }

  function isEmpty(v) {
    return isNullOrUnDef(v) || v === '';
  }

  // ============ 获取字段 end ==========
</script>
<style lang="less" scoped>
  @prefix-cls: ~'@{namespace}-DataInfoTable';
  .@{prefix-cls} {
    ::v-deep(.dataInfo) {
      max-height: calc(100vh - 128px);
    }
  }
</style>
